"""
@File    :   validate.py
@Time    :   2024/03/25 14:07:39
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   Token相关的pydantic验证模型
"""

from datetime import datetime

from pydantic import BaseModel, Field, constr

from src.business.admin.system.oauth2.auth.enums import OAuth2GrantTypeEnum
from src.business.admin.system.oauth2.token.enums import TokenTypeEnum
from src.config import get_app_settings
from src.schemas.validate import (
    BaseSearchValidateSchemaMixin,
    BaseValidateSchemaConfigMixin,
)
from src.utils.uuid import UuidUtil

settings = get_app_settings()


class RefreshTokenCreateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于创建刷新令牌的验证模型"""

    tenant_id: int = Field(default=..., ge=1, description="租户ID")
    tenant_is_system: bool = Field(default=..., description="是否系统级别租户")
    tenant_pakcage_id: int = Field(default=..., ge=0, description="租户套餐ID")
    create_datetime: datetime = Field(
        default=..., default_factory=datetime.now, description="创建时间"
    )
    expiration_datetime: datetime = Field(default=..., description="过期时间")
    oauth2_client_id: int = Field(default=..., ge=1, description="OAuth2客户端ID")
    oauth2_grant_type: OAuth2GrantTypeEnum = Field(
        default=..., description="OAuth2授权方式"
    )
    oauth2_scopes: list[constr(min_length=1, max_length=100)] = Field(
        default_factory=list, description="OAuth2授权范围"
    )
    user_id: int = Field(default=0, ge=1, description="用户ID")
    username: str = Field(default="", min_length=1, max_length=20, description="用户名")
    user_is_admin: bool = Field(default=False, description="是否管理员用户")
    token_type: TokenTypeEnum = Field(
        default=TokenTypeEnum.bearer.value, description="令牌类型(有的swagger需要)"
    )  # 一般保持默认值bearer即可
    refresh_token: str = Field(
        default_factory=UuidUtil.generate_uuid1,
        min_length=1,
        max_length=255,
        description="刷新令牌",
    )


class AccessTokenCreateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于创建访问令牌的验证模型"""

    tenant_id: int = Field(default=..., ge=1, description="租户ID")
    tenant_is_system: bool = Field(default=..., description="是否系统级别租户")
    tenant_pakcage_id: int = Field(default=..., ge=0, description="租户套餐ID")
    create_datetime: datetime = Field(
        default=..., default_factory=datetime.now, description="创建时间"
    )
    expiration_datetime: datetime = Field(default=..., description="过期时间")
    oauth2_client_id: int = Field(default=..., ge=1, description="OAuth2客户端ID")
    oauth2_grant_type: OAuth2GrantTypeEnum = Field(
        default=..., description="OAuth2授权方式"
    )
    oauth2_scopes: list[constr(min_length=1, max_length=100)] = Field(
        default_factory=list, description="OAuth2授权范围"
    )
    user_id: int = Field(default=0, ge=1, description="用户ID")
    username: str = Field(default="", min_length=1, max_length=20, description="用户名")
    user_is_admin: bool = Field(default=False, description="是否管理员用户")
    token_type: TokenTypeEnum = Field(
        default=TokenTypeEnum.bearer.value, description="令牌类型(有的swagger需要)"
    )  # 一般保持默认值bearer即可
    access_token: str = Field(
        default_factory=UuidUtil.generate_uuid1,
        min_length=1,
        max_length=255,
        description="访问令牌",
    )
    refresh_token: str = Field(
        default_factory=UuidUtil.generate_uuid1,
        min_length=1,
        max_length=255,
        description="关联的刷新令牌",
    )


class DoubleTokenCreateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于创建双Token的验证模型"""

    tenant_id: int = Field(default=..., ge=1, description="租户ID")
    tenant_is_system: bool = Field(default=..., description="是否系统级别租户")
    tenant_pakcage_id: int = Field(default=..., ge=0, description="租户套餐ID")
    oauth2_client_id: int = Field(default=..., ge=1, description="OAuth2客户端ID")
    oauth2_grant_type: OAuth2GrantTypeEnum = Field(
        default=..., description="OAuth2授权方式"
    )
    access_token_expiration_seconds: int = Field(
        default=settings.oauth2_access_token_default_expiration_seconds,
        ge=settings.oauth2_access_token_min_expiration_seconds,
        le=settings.oauth2_access_token_max_expiration_seconds,
        description="访问令牌过期秒数",
    )  # 最多6小时
    refresh_token_expiration_seconds: int = Field(
        default=settings.oauth2_refresh_token_default_expiration_seconds,
        ge=settings.oauth2_refresh_token_min_expiration_seconds,
        le=settings.oauth2_refresh_token_max_expiration_seconds,
        description="刷新令牌过期秒数",
    )  # 最多15天
    user_id: int = Field(default=0, ge=1, description="用户ID")
    username: str = Field(default="", min_length=1, max_length=20, description="用户名")
    user_is_admin: bool = Field(default=False, description="是否管理員用戶")
    user_number_of_simultaneous_logins: int = Field(
        default=1, ge=1, le=1000, description="用户可同时登录数量"
    )
    oauth2_scopes: list[str] = Field(
        default_factory=list, description="拥有的OAuth2授权范围"
    )
    occupation_of_login_quota: bool = Field(
        default=True, description="是否占用登录名额"
    )
    access_token: str = Field(
        default_factory=UuidUtil.generate_uuid1,
        min_length=1,
        max_length=255,
        description="访问令牌",
    )
    refresh_token: str = Field(
        default_factory=UuidUtil.generate_uuid1,
        min_length=1,
        max_length=255,
        description="关联的刷新令牌",
    )


class AccessTokenListSearchValidateSchema(BaseModel, BaseSearchValidateSchemaMixin):
    """用于查询双Token列表的验证模型"""

    tenant_is_system: bool | None = Field(default=None, description="是否系统级别租户")
    create_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="创建时间",
        json_schema_extra={"allow_order": True},
    )
    expiration_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="过期时间",
        json_schema_extra={"allow_order": True},
    )
    username: str = Field(
        default="",
        min_length=1,
        max_length=20,
        description="用户名",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    user_is_admin: bool | None = Field(default=None, description="是否管理员用户")
    access_token: str | None = Field(
        default_factory=None, min_length=1, max_length=255, description="访问令牌"
    )
    refresh_token: str | None = Field(
        default_factory=None, min_length=1, max_length=255, description="关联的刷新令牌"
    )


class RefreshTokenLogoutCreateValidateSchema(BaseModel, BaseSearchValidateSchemaMixin):
    """的验证模型"""

    refresh_token_list: list[constr(min_length=1, max_length=255)] = Field(
        default=..., min_length=1, description="需删除的刷新令牌列表"
    )
